// alert('skeletonScript.js')
window.Skeleton = (function () {
  const $$ = document.querySelectorAll.bind(document);
  const REMOVE_TAGS = ['title', 'meta', 'style', 'script'];
  const CLASS_NAME_PREFIX = 'sk-';
  const styleCache = new Map();
  const SMALLEST_BASE64 = ''; //宽1px 高1px的透明gif图

  //转换原始元素为骨架屏DOM元素
  function genSkeleton(options){
    const rootElement = document.documentElement;
    ;(function traverse(options){
      const {button:buttonOpt, image:imageOpt} = options;
      const buttons = []  // 所有的按钮
      const imgs = [];  //所有的图片

      //深度遍历
      ;(function preTraverse(element) {
        if (element.children && element.children.length > 0) {
          Array.from(element.children).forEach(child => preTraverse(child));
        }
        if(element.tagName === 'BUTTON'){
          buttons.push(element);
        }else if(element.tagName === 'IMG'){
          imgs.push(element);
        }
      })(rootElement);

      buttons.forEach(item => buttonHandler(item, buttonOpt));
      imgs.forEach(item => imageHandler(item, imageOpt));
    })(options)

    let rules = '';
    for (const [selector, rule] of styleCache) {
      // .sk-button {...}
      // ...
      rules += `${selector} ${rule}\n`;
    }
    // console.log('rules:',rules);
    const styleElement = document.createElement('style');
    styleElement.innerHTML = rules;
    document.head.appendChild(styleElement);
  }

  //获得DOM元素的HTML字符串和样式style
  function getHtmlAndStyle(){
    const styles = Array.from($$('style')).map(style => style.innerHTML || style.innerText);
    Array.from($$(REMOVE_TAGS.join(','))).forEach(ele => ele.parentNode.removeChild(ele));
    const html = document.body.innerHTML;
    return {html, styles};
  }


  function buttonHandler(element, options = {}) {
    const className = CLASS_NAME_PREFIX + 'button'; //sk-button
    const rule = `{
      color:${options.color}!important;
      background:${options.color}!important;
      border:none!important;
      box-shadow:none!important;
    }`;
    addStyle(`.${className}`, rule);
    element.classList.add(className)
  }
  function addStyle(selector,rule){
    if (!styleCache.has(selector)) {
      styleCache.set(selector, rule);
    }
  }

  function imageHandler(element, options = {}) {
    const {width, height} = element.getBoundingClientRect();
    const attrs = {
      width, height, src: SMALLEST_BASE64
    };
    setAttributes(element, attrs);
    const className = CLASS_NAME_PREFIX + 'image';
    const rule = `{
      background: ${options.color}!important;
    }`;
    addStyle(`.${className}`, rule);
    element.classList.add(className)
  }
  function setAttributes(element, attrs){
    Object.keys(attrs).forEach(key => element.setAttribute(key, attrs[key]));
  }

  return {genSkeleton, getHtmlAndStyle}
})();
